home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
wtek0693.zip
/
OOPALLEY.ZIP
/
ORDCLTN.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-27
|
8KB
|
308 lines
#include <stdlib.h> // prototype for qsort
#include "ordcltn.h"
#define THIS OrderedCltn
#define BASE SeqCltn
DEFINE_CLASS(OrderedCltn,SeqCltn);
OrderedCltn::OrderedCltn(unsigned size) : contents(size)
{
endIndex = 0;
}
OrderedCltn::OrderedCltn(const OrderedCltn& c) : contents(c.contents)
{
endIndex = c.endIndex;
}
void OrderedCltn::operator=(const OrderedCltn& c)
{
endIndex = c.endIndex;
contents = c.contents;
}
bool OrderedCltn::operator==(const OrderedCltn& a) const
{
if (endIndex != a.endIndex) return NO;
else {
register int i = endIndex;
register Object** vv = &contents.elem(0);
register Object** av = &a.at(0);
while (i--) if (!((*vv++)->isEqual(**av++))) return NO;
}
return YES;
}
OrderedCltn OrderedCltn::operator&(const SeqCltn& cltn) const
{
OrderedCltn c(size()+cltn.size());
addContentsTo(c);
cltn.addContentsTo(c);
return c;
}
void OrderedCltn::operator&=(const SeqCltn& cltn)
{
cltn.addContentsTo(*this);
}
Object* OrderedCltn::addAtIndex(int i, const Object& ob)
{
if (endIndex == capacity()) contents.reSize(capacity()+CLTN_EXPANSION_INCREMENT);
for (register int j=endIndex; j>i; j--) contents[j] = contents[j-1];
contents[i] = (Object*)&ob;
endIndex++;
return (Object*)&ob;
}
Object* OrderedCltn::removeAtIndex(int i)
{
register Object* obrem = contents[i];
for (register int j=i+1; j<endIndex; j++) contents[j-1] = contents[j];
#if 0
if (endIndex < capacity()) contents[endIndex--] = (Object*)nil;
#else
// -gmv 2/2/90
// Modified to handle deletion of item
// even when collection is full to capacity.
// endIndex should always be decremented. But the item
// just beyond it is not set to nil if the collection was
// filled to capacity just prior to the deletion.
if (endIndex < capacity()) contents[endIndex] = (Object*)nil;
--endIndex;
#endif
return obrem;
}
Object* OrderedCltn::add(const Object& ob)
{
addAtIndex(endIndex,ob);
return (Object*)&ob;
}
Object* OrderedCltn::addAfter(const Object& ob, const Object& newob)
{
register int i = indexOf(ob);
if (i < 0) errNotFound("addAfter",ob);
return addAtIndex(i+1,newob);
}
Object* OrderedCltn::addAllLast(const OrderedCltn& cltn)
{
if (endIndex+cltn.size() >= capacity())
contents.reSize(endIndex+cltn.size()+CLTN_EXPANSION_INCREMENT);
for (register int i=0; i<cltn.size(); i++) contents[endIndex++] = cltn.contents[i];
return (Object*)&cltn;
}
Object* OrderedCltn::addBefore(const Object& ob, const Object& newob)
{
register int i = indexOf(ob);
if (i < 0) errNotFound("addBefore",ob);
return addAtIndex(i,newob);
}
Collection& OrderedCltn::addContentsTo(Collection& cltn) const
{
for (register int i=0; i<size(); i++) cltn.add(*contents[i]);
return cltn;
}
Object* OrderedCltn::addLast(const Object& ob) { return add(ob); }
Object* OrderedCltn::after(const Object& ob) const
{
register int i=indexOf(ob);
if (i<0) errNotFound("after",ob);
if (++i == endIndex) return (Object*)nil;
return contents[i];
}
Object*& OrderedCltn::at(int i) const { return (*this)[i]; }
void OrderedCltn::atAllPut(const Object& ob)
{
for (register int i=0; i<endIndex; i++) contents[i] = (Object*)&ob;
}
Object* OrderedCltn::before(const Object& ob) const
{
register int i = indexOf(ob);
if (i < 0) errNotFound("before",ob);
if (--i < 0) return (Object*)nil;
return contents[i];
}
unsigned OrderedCltn::capacity() const { return contents.capacity(); }
void OrderedCltn::deepenShallowCopy()
{
BASE::deepenShallowCopy();
contents.deepenShallowCopy();
}
#pragma warn -rvl // Turn of Warning: Function should return a value
Object* OrderedCltn::first() const
{
if (endIndex==0)
{
errEmpty("first"); // aborts, return not executed
// return (Object*)NULL; // avoids Warning message
} else
return contents.elem(0);
}
#pragma warn .rvl
unsigned OrderedCltn::hash() const
{
register unsigned h = endIndex;
register int i = endIndex;
register Object** vv = &contents.elem(0);
while (i--) h^=(*vv++)->hash();
return h;
}
int OrderedCltn::indexOf(const Object& ob) const
{
for (register int i=0; i<endIndex; i++)
if (contents[i]->isEqual(ob)) return i;
return -1;
}
int OrderedCltn::indexOfSubCollection(const SeqCltn& cltn, int start) const
{
int subsize = cltn.size();
for (register int i=start; i<(endIndex-subsize); i++) {
for (register int j=0; j<subsize; j++)
if (!(contents[i+j]->isEqual(*cltn.at(j)))) goto next;
return i;
next:; }
return -1;
}
bool OrderedCltn::isEmpty() const { return endIndex==0; }
bool OrderedCltn::isEqual(const Object& a) const
{
return a.isSpecies(class_OrderedCltn) && *this==*(OrderedCltn*)&a;
}
const Class* OrderedCltn::species() const
{
return &class_OrderedCltn;
}
#pragma warn -rvl // Turn of Warning: Function should return a value
Object* OrderedCltn::last() const
{
if (endIndex==0)
{
errEmpty("last"); // aborts, return not executed
//return (Object*)NULL; // avoids Warning message
} else
return contents.elem(endIndex-1);
}
#pragma warn .rvl
unsigned OrderedCltn::occurrencesOf(const Object& ob) const
{
register unsigned n=0;
for (register int i=0; i<endIndex; i++)
if (contents[i]->isEqual(ob)) n++;
return n;
}
void OrderedCltn::printOn(ostream& strm) const
{
strm << className() << "[\n";
for (register int i=0; i<endIndex; i++) {
if (i>0) strm << "\n";
contents[i]->printOn(strm);
}
strm << "]\n";
}
Object* OrderedCltn::remove(const Object& ob)
{
for (register int i=0; i<endIndex; i++) {
if (contents[i]->isEqual(ob)) {
return removeAtIndex(i);
}
}
return (Object*)nil;
}
Object* OrderedCltn::removeId(const Object& ob)
{
for (register int i=0; i<endIndex; i++) {
if (contents[i] == &ob) {
removeAtIndex(i);
return (Object*)&ob;
}
}
return (Object*)nil;
}
#pragma warn -rvl // Turn of Warning: Function should return a value
Object* OrderedCltn::removeLast()
{
if (endIndex==0)
{
errEmpty("removeLast"); // aborts, return not executed
// return (Object*)NULL; // avoids Warning message
} else
return removeAtIndex(endIndex-1);
}
#pragma warn .rvl
void OrderedCltn::reSize(unsigned newSize)
{
if (newSize > size()) contents.reSize(newSize);
}
void OrderedCltn::replaceFrom(int start, int stop, const SeqCltn& replacement, int startAt)
{
register int j=startAt;
for (register int i=start; i<=stop; i++,j++)
contents[i] = replacement.at(j);
}
static int compare_ob(Object** a, Object** b) { return (*a)->compare(**b); }
unsigned OrderedCltn::size() const { return endIndex; }
void OrderedCltn::sort()
{
//qsort(&contents.elem(0),size(),sizeof(Object*),compare_ob);
qsort(&contents.elem(0),size(),sizeof(Object*),
(int (*)(const void*, const void*))compare_ob); //-gmv added cast
}
void OrderedCltn::errEmpty(const char* fn) const
{
DTerror("", "");
cerr << "Collection empty: "
<< this << "->"
<< className() << "::" << fn << "()"
<< "\n";
}
void OrderedCltn::errNotFound(const char* fn, const Object& ob) const
{
DTerror("Object not found: ",className());
cerr << "Object not found: "
<< this << "->"
<< className() << "::" << fn
<< "((" << ob.className() << "*)"
<< &ob << ")"
<< "\n";
}
OrderedCltn Collection::asOrderedCltn() const
{
OrderedCltn cltn(MAX(size(),CLTN_DEFAULT_CAPACITY));
addContentsTo(cltn);
return cltn;
}